/*
 * Golazo MA4
 * Copyright (C) 2008 Golazo MASHUP AWARD 4th team.
 * http://code.google.com/p/golazo/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Golazo
 */
if (typeof(Golazo) == 'undefined')
  Golazo = {};

// GOOGLE_APIKEY
Golazo.GOOGLE_APIKEY =  'YOUR GOOGLE_APIKEY';

/**
 * Golazo.find
 */
Golazo.find = function(arr, fn) {
  for (var i = 0; i < arr.length; i++)
    if (fn.apply(arr[i], [i, arr[i]]))
      return arr[i];
};

/**
 * Golazo.findAll
 */
Golazo.findAll = function(arr, fn) {
  return $.grep(arr, fn);
};

/**
 * Golazo.each
 */
Golazo.each = function(arr, fn) {
  return $.each(arr, fn);
};

/**
 * Golazo.normalize
 */
Golazo.normalize = function(val) {
  return val; // triming and remove not printable
};

/**
 * Golazo.checkDigit
 */
Golazo.checkDigit = function(val) {
  return !!(val && val.match(/^-?[0-9]+$/));
}

/**
 * Golazo.Geo
 */
if (typeof(Golazo.Geo) == 'undefined')
  Golazo.Geo = {};

/**
 * Golazo.Geo.dmsToDegree
 */
Golazo.Geo.dmsToDegree = function(dms) {
  var degree = dms && dms.match(/^(\+?[0-9]+)\.([0-9]+)\.([0-9]+\.[0-9]+)$/);
  if (!degree)
    throw new Error('`' + dms + '` is missing dms.');
  return parseFloat(degree[1]) +
    parseFloat(degree[2]) / 60 +
    parseFloat(degree[3]) / 3600;
};

/**
 * Golazo.Geo.checkDegree
 */
Golazo.Geo.checkDegree = function(val) {
  return !!(val && val.match(/^-?[0-9]+\.[0-9]+$/));
}

/**
 * Golazo.User
 */
if (typeof(Golazo.User) == 'undefined')
  Golazo.User = {};

/**
 * Golazo.User.checkUserId
 */
Golazo.User.checkUserId = function(val) {
  return !!(val && val.match(/^[a-z][0-9a-z\-_]{0,15}$/));
};

// checkPassword
Golazo.User.checkPassword = function(val) {
  return !!(val && val.match(/^[0-9a-zA-Z]{6,16}$/));
};

/**
 * Golazo.User.checkEmail
 */
Golazo.User.checkEmail = function(val) {
  // http://www.din.or.jp/~ohzaki/perl.htm#Mail
  return !!(val && val.length <= 128 && val.match(/^(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")(?:\.(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*"))*@(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])(?:\.(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]))*$/));
};

// checkNickname
Golazo.User.checkNickname = function(val) {
  return !!(val && val.length <= 16);
};

// checkNote
Golazo.User.checkNote = function(val) {
  return !!(val && val.length <= 64);
};

/**
 * Golazo.User.htmlify
 */
Golazo.User.htmlify = function(user) {
  
  var template = $('.user:hidden')
    .clone()
    .attr('id', 'user_' + user.userId);
	
  $('.content', template)
    .find('.note')
	  .text(user.note);

  if (user.trusted)
    $('.menubar', template)
      .find('span')
	    .toggle();

  $('.groupbar', template)
	.find('a')
      .attr('href', '/you.html?' + $.param({ userId: user.userId }))
	  .end()
	.find('a.userId')
	  .text(user.nickname || user.userId)
	  .end()
	.find('img')
	  .attr('alt', user.nickname || user.userId)
	  .attr('src', user.picture + '?' + user.modified.getTime());

  return template;
};

/**
 * Golazo.User.bind
 */
Golazo.User.bind = function(user) {
  var user = $(user);
  
  $('span.trust > a', user).click(function() {
											  
    var userId = user
	  .attr('id')
	  .substr('user_'.length);

    // 会員を信頼する
	try {
      trustUser(userId);
	} catch (e) {
	  alert(''+e);
	  return false;
	}
	 
	$('div.menubar span', user)
	  .toggle();
	
	return false;
  });

  $('span.distrust > a', user).click(function() {
											  
    if (!confirm('友達をやめます。よろしいですか?'))
	  return false;

    var userId = user
	  .attr('id')
	  .substr('user_'.length);

    // 会員を信頼しない
	try {
      distrustUser(userId);
	} catch (e) {
	  alert(''+e);
	  return false;
	}
	  
	$('div.menubar span', user)
	  .toggle();
	
	return false;
  });

  return user;
};

/**
 * Golazo.User.Subscriber
 */
if (typeof(Golazo.User.Subscriber) == 'undefined')
  Golazo.User.Subscriber = {};

/**
 * Golazo.User.Subscriber
 */
Golazo.User.Subscriber.htmlify = function(user, readonly) {

  var template = $('.subscriber:hidden')
    .clone()
    .attr('id', 'subscriber_' + user.userId);

  $('img', template)
	.attr('alt', user.nickname || user.userId)
    .attr('src', user.picture + '?' + user.modified.getTime());

  $('a', template)
    .attr('href', '/you.html?' + $.param({ userId: user.userId }));

  $('a.userId', template)
	.text(user.nickname || user.userId);
  
  var input = $('input', template)
    .attr('id', 'form_subscriber_' + user.userId)
	.attr('value', user.userId)
	.attr('checked', !!user.subscribed)

  if (readonly)
    input.remove();

  return template;
}

/**
 * Golazo.Action
 */
if (typeof(Golazo.Action) == 'undefined')
  Golazo.Action = {};

/**
 * checkActionId
 */ 
Golazo.Action.checkActionId = function(val) {
  return !!(val && val.match(/^[0-9]+$/));
};

/**
 * Golazo.Action.checkNote 
 */
Golazo.Action.checkNote = function(val) {
  return !!(val && val.length >= 1 && val.length <= 4096);
};

/**
 * Golazo.Action.checkLatitude
 */
Golazo.Action.checkLatitude = function(val) {
  return Golazo.Geo.checkDegree(val);
};

/**
 * Golazo.Action.checkLongitude
 */
Golazo.Action.checkLongitude = function(val) {
  return Golazo.Geo.checkDegree(val);
};

/**
 * Golazo.Action.checkAltitude
 */
Golazo.Action.checkAltitude = function(val) {
  // Google Maps API
  // http://code.google.com/apis/maps/
  return !!(typeof(val) !== 'undefind' && val >= 0 && val <= 19);
};

/**
 * Golazo.Action.htmlify
 */
Golazo.Action.htmlify = function(action) {

  // メモの購読者と作成者
  var subscribers = action.subscribers;
  var creator = action.creator;

  var template = $('.action:hidden')
    .clone()
	.attr('id', 'action_' + action.actionId);

  var altitude = action.altitude - 2;
  if (altitude < 0)
    altitude = 0;

  var note = action.note;
  if (note.length > 256)
    note = note.substr(0, 256) + ' ...'

  $('div.content', template)
    .find('img.map')
      .staticmaps(action.latitude, action.longitude, altitude, 120, 90)
      .end()
    .find('span.note')
	  .text(note);

  $('a.read', template)
    .attr('href', '/read.html?' + $.param({ actionId: action.actionId }));

  if (action.editable)
    $('span.edit', template)
	  .show()
	  .find('a')
        .attr('href', '/edit.html?' + $.param({ actionId: action.actionId }));

  $('a.delete', template)
    .attr('href', '/delete.html?' + $.param({ actionId: action.actionId }));

  $('a.creator', template)
    .attr('href', '/you.html?' + $.param({ userId: action.creatorId }));

  $('img.creator', template)
	  .attr('alt', creator.nickname || creator.userId) 
	  .attr('src', creator.picture + '?' + creator.modified.getTime())
	  .attr('width', 48)
	  .attr('height', 48);

  var carousel = $('div.carousel > ul', template)
    .empty();

  // メモの購読者をリスト表示する
  Golazo.each(subscribers, function(i, subscriber) {

    // メモの作成者は除外する
	//if (subscriber.equals(creator))
	if (subscriber.userId == creator.userId)
	  return;

$('div.carousel-prev,div.carousel-next', template)
  .show();

    var img = $('<img />')
	  .attr('alt', subscriber.nickname || subscriber.userId) 
	  .attr('src', subscriber.picture + '?' + subscriber.modified.getTime())
	  .attr('width', 32)
	  .attr('height', 32);
    
	var a = $('<a />')
	  .attr('href', '/you.html?' + $.param({ userId: subscriber.userId }))
	  .append(img);
	
	$('<li />')
      .append(a)
      .appendTo(carousel);
  });

  return template;
};

/**
 * Golazo.Action.bind
 */
Golazo.Action.bind = function(action) {
  var action = $(action);
  
  $('span.delete > a', action).click(function() {
											  
    if (!confirm('メモを削除します。よろしいですか？'))
	  return false;
	
    var actionId = action
	  .attr('id')
	  .substr('action_'.length);

    // メモを削除する
	try {
      deleteAction(actionId);
	} catch (e) {
	  alert(''+e);
	  return false;
	}
	  
	action.fadeOut('slow', function() {
	  $(this).remove();
	});
	
	return false;
  });
  
  return action;
};

/**
 * $.fn.staticmaps
 */ 
$.fn.staticmaps = function(lat, lng, alt, width, height) {
  var latlng = lat + ',' + lng;
  
  var url = 'http://maps.google.com/staticmap?' +
    $.param({  
      center: latlng,
      zoom: alt,
      size: [
	    this.attr('width') || width,
		this.attr('height') || height
	  ].join('x'),
      markers: latlng,
      key: Golazo.GOOGLE_APIKEY
  });

  this.attr('alt', latlng);
  this.attr('src', url);
  
  return this;
};

